#region Using References

using System.Diagnostics.Contracts;
using Beaker.OpenCube.Mapping;
using Beaker.OpenCube.Nbt;

#endregion

namespace Beaker.OpenCube.Game
{
	/// <summary>
	/// The game rules
	/// </summary>
	public sealed class GameRules
		: ObservableExpandoObject
	{
		private bool _commandBlockOutput;

		/// <summary>
		/// Gets or sets a value indicating whether or not actions performed by command blocks are displayed in the chat.
		/// </summary>
		/// <value>
		///   <c>true</c> if actions performed by command blocks are displayed in the chat; otherwise, <c>false</c>.
		/// </value>
		[Mapping( Tag = NbtTag.String, Name = "commandBlockOutput" )]
		public bool CommandBlockOutput
		{
			get
			{
				Contract.Ensures( Contract.Result<bool>() == _commandBlockOutput );
				return _commandBlockOutput;
			}
			set
			{
				Contract.Ensures( _commandBlockOutput == value );
				SetValue( ref _commandBlockOutput, value );
			}
		}

		private bool _doFireTick;

		/// <summary>
		/// Gets or sets a value indicating whether to spread or remove fire.
		/// </summary>
		/// <value>
		///   <c>true</c> if fire spreads; otherwise, <c>false</c>.
		/// </value>
		[Mapping( Tag = NbtTag.String, Name = "doFireTick" )]
		public bool DoFireTick
		{
			get
			{
				Contract.Ensures( Contract.Result<bool>() == _doFireTick );
				return _doFireTick;
			}
			set
			{
				Contract.Ensures( _doFireTick == value );
				SetValue( ref _doFireTick, value );
			}
		}

		private bool _doMobLoot;

		/// <summary>
		/// Gets or sets a value indicating whether mobs should drop loot when killed.
		/// </summary>
		/// <value>
		///   <c>true</c> if mobs drop loot when killed; otherwise, <c>false</c>.
		/// </value>
		[Mapping( Tag = NbtTag.String, Name = "doMobLoot" )]
		public bool DoMobLoot
		{
			get
			{
				Contract.Ensures( Contract.Result<bool>() == _doMobLoot );
				return _doMobLoot;
			}
			set
			{
				Contract.Ensures( _doMobLoot == value );
				SetValue( ref _doMobLoot, value );
			}
		}

		private bool _doMobSpawning;

		/// <summary>
		/// Gets or sets a value indicating whether mobs should spawn naturally.
		/// </summary>
		/// <value>
		///   <c>true</c> if mobs spawn naturally; otherwise, <c>false</c>.
		/// </value>
		[Mapping( Tag = NbtTag.String, Name = "doMobSpawning" )]
		public bool DoMobSpawning
		{
			get
			{
				Contract.Ensures( Contract.Result<bool>() == _doMobSpawning );
				return _doMobSpawning;
			}
			set
			{
				Contract.Ensures( _doMobSpawning == value );
				SetValue( ref _doMobSpawning, value );
			}
		}

		private bool _doTileDrops;

		/// <summary>
		/// Gets or sets a value indicating whether breaking blocks should drop the block's item drop.
		/// </summary>
		/// <value>
		///   <c>true</c> if breaking blocks drop the block's item drop; otherwise, <c>false</c>.
		/// </value>
		[Mapping( Tag = NbtTag.String, Name = "doTileDrops" )]
		public bool DoTileDrops
		{
			get
			{
				Contract.Ensures( Contract.Result<bool>() == _doTileDrops );
				return _doTileDrops;
			}
			set
			{
				Contract.Ensures( _doTileDrops == value );
				SetValue( ref _doTileDrops, value );
			}
		}

		private bool _keepInventory;

		/// <summary>
		/// Gets or sets a value indicating whether players keep their inventory after they die.
		/// </summary>
		/// <value>
		///   <c>true</c> if players keep their inventory after they die; otherwise, <c>false</c>.
		/// </value>
		[Mapping( Tag = NbtTag.String, Name = "keepInventory" )]
		public bool KeepInventory
		{
			get
			{
				Contract.Ensures( Contract.Result<bool>() == _keepInventory );
				return _keepInventory;
			}
			set
			{
				Contract.Ensures( _keepInventory == value );
				SetValue( ref _keepInventory, value );
			}
		}

		private bool _mobGriefing;

		/// <summary>
		/// Gets or sets a value indicating whether mobs can destroy blocks (creeper explosions, zombies breaking doors, etc.).
		/// </summary>
		/// <value>
		///   <c>true</c> if mobs can destroy blocks (creeper explosions, zombies breaking doors, etc.); otherwise, <c>false</c>.
		/// </value>
		[Mapping( Tag = NbtTag.String, Name = "mobGriefing" )]
		public bool MobGriefing
		{
			get
			{
				Contract.Ensures( Contract.Result<bool>() == _mobGriefing );
				return _mobGriefing;
			}
			set
			{
				Contract.Ensures( _mobGriefing == value );
				SetValue( ref _mobGriefing, value );
			}
		}
	}
}